/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-17
*/
package com.rzico.basics.service;

import com.alibaba.fastjson.JSON;
import com.rzico.base.BaseMapper;
import com.rzico.base.impl.BaseServiceImpl;
import com.rzico.basics.entity.*;
import com.rzico.basics.mapper.CompanyEmployeeMapper;
import com.rzico.core.entity.SysMch;
import com.rzico.core.entity.SysUser;
import com.rzico.core.service.SysMchService;
import com.rzico.core.service.SysUserService;
import com.rzico.util.CodeGenerator;
import com.rzico.util.RedisHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import com.rzico.basics.mapper.MemberMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <pre>
 * 会员业务类
 * </pre>
 *
 * @author Rzico Boot
 * @version 1.0
 */
@Service
public class MemberService extends BaseServiceImpl<Member, String> {

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private CompanyEmployeeMapper companyEmployeeMapper;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private SysMchService sysMchService;

    @Autowired
    private RedisHandler redisHandler;

    @Autowired  @Lazy
    private MsgService msgService;

    @Override
    public BaseMapper<Member, String> getMapper() {
        return memberMapper;
    }

    @Transactional(rollbackFor = Exception.class)
    public Member getCurrent() {
        SysUser sysUser = sysUserService.getCurrent();
        if (sysUser!=null) {
            while (!redisHandler.lock(sysUser.getId(),sysUser.getId())) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("redis-lock=>"+sysUser.getId());
            }
            try {
                Member member = findByUserId(sysUser.getId());
                if (member != null) {
                    return member;
                } else {
                    return register(sysUser,sysUser.getMchId());
                }
            } finally {
                redisHandler.unlock(sysUser.getId(),sysUser.getId());
            }
        }
        return null;
    }

    public Integer clearFreezeBalance() {
        return memberMapper.clearFreezeBalance();
    }

    @Override
    public int updateByPrimaryKeySelective(Member member) {
        member.setPoint(null);
        member.setMatchPoint(null);
        member.setBalance(null);
        member.setFreezeBalance(null);
        member.setFreezePoint(null);
        return memberMapper.updateByPrimaryKeySelective(member);
    }


    public Member findByUsername(String username) {
        Map<String,Object> params = new HashMap<>();
        params.put("username",username);
        List<Member> members = super.selectList(params);
        if (members.size()>0) {
            return members.get(0);
        } else {
            return null;
        }
    }

    public Member findByUserId(String userId) {

//        String key = "member:" + userId;
//        Member member = (Member)redisHandler.get(key);
//        if (null != member){
//            return member;
//        }else{

            Map<String,Object> params = new HashMap<>();
            params.put("userId",userId);
            List<Member> members = super.selectList(params);
            if (members.size()>0) {
//                redisHandler.set(key, members.get(0), RedisHandler.CACHE_EXPIRED_TIME_TWO_HOURS);
                return members.get(0);
            } else {
                return null;
            }
//        }

    }


    public Member findByMobile(Long enterpirseId,String mobile){
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(enterpirseId);

        String mchId = enterprise.getMchId();

        SysMch sysMch = sysMchService.selectByPrimaryKey(mchId);
        if (sysMch.getMchType().equals(2) || sysMch.getMchType().equals(1)) {
            mchId = sysMch.getIsvId();
        }
        return findByMchMobile(mchId,mobile);
    }


    //获取店主会员记录
    public Member findByOwner(Long enterpirseId){
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(enterpirseId);
        Member member = memberMapper.selectByPrimaryKey(enterprise.getMemberId());
        return member;
    }

    public Member findByMchMobile(String mchId,String mobile){
        Map<String,Object> params = new HashMap<>();
        params.put("mchId",mchId);
        params.put("mobile",mobile);
        params.put("sortField","id");
        params.put("sortType","asc");
        List<Member> members = selectList(params);
        if (members.size()>0) {
            return members.get(0);
        } else {
            return null;
        }
    }

    //通过登录用户注册会员
    @Transactional(rollbackFor = Exception.class)
    public Member register(SysUser sysUser,String mchId) {

        Enterprise enterprise = enterpriseService.findByMch(mchId);
        if (enterprise!=null) {
            mchId = enterprise.getMchId();
            SysMch sysMch = sysMchService.selectByPrimaryKey(mchId);
            if (sysMch.getMchType().equals(1) || sysMch.getMchType().equals(2)) {
                mchId = sysMchService.getIsvId(sysMch);
            }
        }

        Member member = null;
        String username = sysUser.getUsername();

        if (sysUser.getMobile()!=null)  {
            member = findByMchMobile(mchId,sysUser.getMobile());
            if (sysUser.getUserType().equals(1)) {
                //店主商号+员工号只能扫码绑定
                if (sysUser.getMobile()!=null)  {
                    username = "mch_"+sysUser.getMchId()+"_"+sysUser.getMobile();
                }
            }
        }

        if (member==null) {
            member = findByUsername(username);
        }

        if (member==null) {
            member = new Member();
            if (enterprise!=null) {
                member.setEnterpriseId(enterprise.getId());
                member.setMchId(enterprise.getMchId());
            }
            member.setUserId(sysUser.getId());
            member.setUsername(username);
            member.setMobile(sysUser.getMobile());
            member.setName(sysUser.getNickname());
            member.setMchId(mchId);

            member = createMember(member);
        } else {
            member.setMchId(sysUser.getMchId());
            member.setUserId(sysUser.getId());
            member.setUsername(username);
            super.updateByPrimaryKeySelective(member);
        }

        //Map<String,Object> content = new HashMap<>();
        //content.put("title","新会员通知");
        //content.put("content",member.getName().concat("注册成为新会员"));
        //msgService.sendNotity(member,"msg-notify",member.getName().concat("注册成为新会员"), JSON.toJSONString(content),null);

        return member;

    }

    public Member findByCode(String mchId,String code) {
        Map<String,Object> params = new HashMap<>();
        params.put("mchId",mchId);
        params.put("code",code);
        List<Member> memberList = memberMapper.selectList(params);
        if (memberList.size()>0) {
            return memberList.get(0);
        } else {
            return null;
        }
    }


    public String getMaxCode(String mchId) {
        Map<String,Object> params = new HashMap<>();
        params.put("mchId",mchId);
        String code = memberMapper.getMaxCode(params);
        if (code==null) {
            return "100000";
        } else {
            return String.valueOf(Long.valueOf(code)+1L);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Member createMember(Member member) {
        member.setCreateDate(new Date());
        if (member.getUsername()==null) {
            member.setUsername(CodeGenerator.getUUID());
        }
        member.setDeleted(false);
        member.setBalance(BigDecimal.ZERO);
        member.setFreezeBalance(BigDecimal.ZERO);
        member.setPoint(0L);
        member.setFreezePoint(0L);
        member.setAmount(BigDecimal.ZERO);
        if (member.getCode()==null || "".equals(member.getCode())) {
            member.setCode(getMaxCode(member.getMchId()));
        }
        if (member.getVip()==null) {
            member.setVip(0);
        }
        if (member.getAchieve()==null) {
            member.setAchieve(BigDecimal.ZERO);
        }
        if (member.getMatchPoint()==null) {
            member.setMatchPoint(0L);
        }
        if (member.getMemberType()==null) {
            member.setMemberType(0);
        }
        if (member.getGender()==null) {
            member.setGender(2);
        }
        if (member.getTaxType()==null) {
            member.setTaxType(0);
        }
        if (member.getPaymentPluginId()==null) {
            member.setPaymentPluginId("cashPayPlugin");
        }
        super.insertUseGeneratedKeys(member);
        return member;

    }

    @Transactional(rollbackFor = Exception.class)
    public void moveTo(Member member,Shop shop) {
       member.setEnterpriseId(shop.getEnterpriseId());
       member.setShopId(shop.getId());
       super.updateByPrimaryKeySelective(member);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteByIds(Object [] ids) {
        int rw = 0;
        for (Object id:ids) {
            Member member = selectByPrimaryKey(id);
            member.setDeleted(true);
            rw = rw + super.updateByPrimaryKeySelective(member);
        }
        return rw;
    }

    //会员统计
    public List<Map<String,Object>>  summary(Map<String, Object> params) {
        return memberMapper.summary(params);
    }

    public BigDecimal summaryRebate(Member member) {
        Map<String,Object> params = new HashMap<>();
        params.put("memberId",member.getId());
        Double d = memberMapper.summaryRebate(params);
        if (d!=null) {
            return new BigDecimal(d);
        } else {
            return BigDecimal.ZERO;
        }
    }

    public int summaryOrder(Member promoter) {
        Map<String,Object> params = new HashMap<>();
        params.put("promoterId",promoter.getId());
        return memberMapper.summaryOrder(params);
    }



//    @CachePut(value = "member", key = "#record.userId", unless = "#result eq null ")
    public Member update(Member record) {

        Member member = null;
        int affectCount = super.updateByPrimaryKeySelective(record);
        if (affectCount > 0){
            member = this.findById(record.getId());
            //检查企业关系
            if (member.getCompanyId()!=null) {
                Map<String,Object> params = new HashMap<>();
                params.put("memberId",member.getId());
                params.put("enterpriseId", record.getEnterpriseId());
                CompanyEmployee companyEmployee = null;
                List<CompanyEmployee> employeeList = companyEmployeeMapper.selectList(params);
                for (CompanyEmployee ce:employeeList) {
                    if (ce.getCompanyId().equals(member.getCompanyId())) {
                        ce.setStatus(1);
                        companyEmployee = ce;
                    } else {
                        ce.setStatus(0);
                    }
                    companyEmployeeMapper.updateByPrimaryKeySelective(ce);
                }

                if (null == companyEmployee){
                    //再插入员工与企业关联信息，companyEmployee表
                    companyEmployee = new CompanyEmployee();
                    companyEmployee.setCompanyId(member.getCompanyId());
                    companyEmployee.setMemberId(member.getId());
                    companyEmployee.setJob(null);
                    companyEmployee.setStatus(1);
                    companyEmployee.setEnterpriseId(member.getEnterpriseId());
                    companyEmployeeMapper.insertUseGeneratedKeys(companyEmployee);
                }

            }
        }
        return member;

    }

    public Member findByAreaAgent(Long enterpriseId,Integer areaId) {

        Map<String,Object> params = new HashMap<>();
        params.put("areaId",areaId);
        params.put("vipType",2);
        params.put("deleted",false);
        params.put("enterpriseId",enterpriseId);
        List<Member> memberList = memberMapper.selectList(params);
        if (memberList.size()>0) {
            return memberList.get(0);
        } else {
            String id = String.valueOf(areaId);
            if (id.endsWith("0000")) {
                return null;
            } else if (id.endsWith("00")) {
                id = id.substring(0, 2);
                return findByAreaAgent(enterpriseId, Integer.valueOf(id.concat("0000")));
            } else {
                id = id.substring(0, 4);
                return findByAreaAgent(enterpriseId, Integer.valueOf(id.concat("00")));
            }
        }
    }

    public Member getAgent(Long memberId,Integer lv) {

        Member member = super.findById(memberId);
        if (member==null) {
            return null;
        }

        Vip vip = member.vipObject();
        if (vip!=null && vip.getVipType().equals(1)) {
            return member;
        }

        if (member.getPromoterId()==null) {
            return null;
        } else {
            if (lv>10) {
                return null;
            }
            return getAgent(member.getPromoterId(),lv+1);
        }

    }

    public List<Long> selecMemberIdByTalentIdList(Map<String, Object> followParams) {
        return memberMapper.selecMemberIdByTalentIdList(followParams);
    }
}
